<?php
/**
 * 记录表所有字段的变化 操作人，操作ip，操作时间
 */
namespace Watcher;

use think\Db;
use think\Exception;

class WatchUpdate
{
    public static $_instance = null;
    public static $config = [
        'ingore_field' => ['id','listorder' ,'add_time' ,'update_time'] , //忽略的字段
        'watchTable' => '',
        'logTable' => '',
    ];


    public function __construct(){return;}

    public static function init( $config = [])
    {
        if(self::$_instance == null){
            self::$_instance = new self();
        }
        self::$config = array_merge(self::$config ,$config);

        if(!isset(self::$config['watchDb'])) self::$config['watchDb'] = self::getDb(self::$config['watchTable']);
        if(!isset(self::$config['logDb'])) self::$config['logDb'] = self::getDb(self::$config['logTable']);


        return self::$_instance;
    }


    public function log($filermap = [])
    {

        $old = self::$config['oldData'];
        $new = self::$config['newData'];
        $diff  = array_diff_assoc($new ,$old);

        $change_field = $content = '';
        foreach ($diff as $k => $v){
            $change_field .= "'{$k}'".',';
        }
        $change_field = trim($change_field ,' , ');


        //没有改变直接返回true
        if(strlen($change_field) <= 0) return true;

        $res = Db::query('Select COLUMN_NAME as fieldname,COLUMN_COMMENT  as evenName from INFORMATION_SCHEMA.COLUMNS Where table_name = \''.config('database.prefix').self::$config['watchTable'].'\'  AND table_schema = \''.config('database.database').'\' AND column_name in ('.$change_field.') ');
        $comment = [];
        foreach ($res as $k => $v){
            $comment[$v['fieldname']] = $v['evenName'];
        }
        foreach ($diff as $k => $v){
            if(isset($filermap[$k])){
                $old[$k] = $this->getFilterValue($filermap[$k] ,$old[$k]);
                $new[$k] = $this->getFilterValue($filermap[$k] ,$new[$k]);
            }
            $content .= $comment[$k].': '.($old[$k] ? $old[$k] : '空').' -> '.($new[$k] ? $new[$k] : '空') .' , ';
        }

        $content = trim($content ,' , ');

        $logdata['manager_id'] = session('manager.id');
        $logdata['ip'] = session('manager.last_login_ip');
        $logdata['content'] = $content;
        $logdata['add_time'] = date('Y-m-d H:i:s' ,time());


        $flag = self::$config['logDb']->insert($logdata);
        return $flag;


    }

    private static function getDb($table)
    {
        $res = Db::query('SELECT table_name FROM information_schema.TABLES WHERE table_name =\''.config('database.prefix').$table.'\'');
        if(!count($res))throw new Exception('watchTable not exists');
        return Db::name($table);
    }
    private function getFilterValue($arr ,$item_id){
        $pk = Db::name(key($arr))->getPk();
        $res = Db::name(key($arr))->where($pk,$item_id)->value($arr[key($arr)]);
        return $res ;
    }

    public function getOldData($itemId){
        $res = self::$config['watchDb']->find($itemId);
        if(!count($res))throw new Exception('itemId not exists');
        foreach ($res as $k => $v){
            if(in_array($k ,self::$config['ingore_field']))continue;
            self::$config['oldData'][$k] = $v;
        }

        return self::$_instance;
    }

    public function getNewData($data){
        foreach ($data as $k => $v){
            if(in_array($k ,self::$config['ingore_field']))continue;
            self::$config['newData'][$k] = $v;
        }


        return self::$_instance;
    }



}